﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using ProgNetComponentsDx.Forms;

namespace ProgNetComponentsDx.Controls
{
    public class ProgressReporter : Component
    {
        private Timer timer = new Timer();
        private object lockProgress = new object();
        private int _Progress =0;
        private DateTime dtStart;
        private TimeSpan ts;
        private TimeSpan pozostało;

        public event StringEventHandler GetLabel1Text;
        public event StringEventHandler GetLabel2Text;

        private string OnGetLabel1Text(string text)
        {
            if (GetLabel1Text != null)
            {
                StringEventArgs e = new StringEventArgs(text);
                GetLabel1Text(this, e);
                return e.Value;
            }
            return text;
        }
        private string OnGetLabel2Text(string text)
        {
            if (GetLabel2Text != null)
            {
                StringEventArgs e = new StringEventArgs(text);
                GetLabel2Text(this, e);
                return e.Value;
            }
            return text;
        }

        public ProgressReporter()
        {
            timer.Tick += new EventHandler(timer_Tick);
            timer.Interval = 1000;
            ShowProgressLabel = true;
            ShowTimeLabel = true;
        }
        public ProgressReporter(IContainer container)
            : this()
        {
            container.Add(this);
        }

        public int Progress
        {
            get
            {
                lock (lockProgress)
                {
                    return _Progress;
                }
            }
            set
            {
                lock (lockProgress)
                {
                    _Progress = value;
                }
            }
        }
        public int Interval
        {
            get { return timer.Interval; }
            set { timer.Interval = value; }
        }
        public bool ShowProgressLabel
        {
            get;
            set;
        }
        public bool ShowTimeLabel
        {
            get;
            set;
        }

        public FormBackgroundWorkBase Form
        {
            get;
            set;
        }

        public void Start()
        {
            Progress = 0;
            dtStart = DateTime.Now;
            timer.Start();
        }
        public void Stop()
        {
            timer.Stop();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            SetProgress();
        }

        private void SetProgress()
        {
            try
            {
                if (Form != null &&
                    !Form.IsDisposed &&
                    !Form.Disposing &&
                    Form.BackgroundControl.MaxProgress > 0 && Progress > 0)
                {
                    Form.BackgroundControl.Progress = Progress;

                    if (ShowProgressLabel)
                        Form.BackgroundControl.LabelText = (OnGetLabel1Text(Progress + " / " + Form.BackgroundControl.MaxProgress));
                    if (ShowTimeLabel)
                    {
                        ts = DateTime.Now - dtStart;
                        pozostało = new TimeSpan((ts.Ticks / Progress) * (Form.BackgroundControl.MaxProgress) - ts.Ticks);
                        Form.BackgroundControl.Label2Text = (OnGetLabel2Text("Upłynęło: " + ts.ToString(@"dd\ hh\:mm\:ss") + "\n Pozostało: " + pozostało.ToString(@"dd\ hh\:mm\:ss")));
                    }
                }
            }
            catch (Exception ex)
            {
                ex.Log();
            }
        }
    }

    public delegate void StringEventHandler(object sender, StringEventArgs e);

    public class StringEventArgs : EventArgs
    {
        public StringEventArgs(string value = null)
        {
            Value = value;
        }
        public string Value
        {
            get;
            set;
        }
    }
}
